/*
 * @Author: lei
 * @Description: any基本使用及简单实现
 * @FilePath: /C++_world/any.cc
 */
// compile: g++ -o any any.cc -std=c++17
// run: ./any
#include <any>
#include <iostream>
#include <memory>
class Base {
 public:
  virtual ~Base() = default;

 private:
};
template <typename T>
class Derived : public Base {
 public:
  Derived(T data) : data_(data) {}
  ~Derived() = default;

 public:
  T data_;
};
class Any {
 public:
  Any() = default;
  ~Any() = default;
  Any(const Any&) = delete;
  Any& operator=(const Any&) = delete;
  Any(Any&&) = default;
  Any& operator=(Any&&) = default;

  template <typename T>
  Any(T data) : base_(std::make_unique<Derived<T>>(data)) {}

  template <typename T>
  T Any_Cast() {
    Derived<T>* ptr = dynamic_cast<Derived<T>*>(base_.get());
    if (ptr == nullptr) throw "target type is unmatched!";
    return ptr->data_;
  }

 private:
  std::unique_ptr<Base> base_;
};
void Test1() {
  std::any a = 3;
  int b = std::any_cast<int>(a);  // 成功
  // double c = std::any_cast<double>(a);
  // terminate called after throwing an instance of 'std::bad_any_cast'
  // what():  bad any_cast
}
void Test2() {
  Any a = 3;
  int b = a.Any_Cast<int>();
  // double c = a.Any_Cast<double>();类型不匹配，抛出异常
}
int main() {
  // Test1();
  Test2();
  return 0;
}